export function SDku(n) {
    this.num = n;
    this.sdArr = [];
    this.backupSdArr = [];

    if (n === 4) this.numArr = [1, 2, 3, 4];
    else if (n === 9) this.numArr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
}

SDku.prototype = {
    constructor: SDku,
    init: function () {
        this.createSdArr();
        this.createBlank();
    },
    createSdArr: function () {
        let self = this;
        try {
            if (this.num === 4) this.sdArr = [[], [], [], []];
            else if (this.num === 9) this.sdArr = [[], [], [], [], [], [], [], [], []];

            for (let i = 0; i < this.num; i++) {
                for (let j = 0; j < this.num; j++) {
                    let xyArr = this.getXY(i, j);
                    let thArr = this.getThArr(i, j);
                    let sumArr = this.getSumArr(xyArr, thArr);
                    let resArr = this.getResArr(sumArr, this.numArr);

                    if (resArr.length > 0) this.sdArr[i][j] = resArr[parseInt(Math.random() * resArr.length)];
                    else {
                        this.createSdArr();
                        return;
                    }
                }
            }

            this.backupSdArr = JSON.parse(JSON.stringify(this.sdArr));
            return this.sdArr;
        } catch (e) {
            self.createSdArr();
        }
    },
    getXY: function (i, j) {
        let xArr = [], yArr = [];
        for (let k = 0; k < this.num; k++) {
            if (this.sdArr[k][j]) xArr.push(this.sdArr[k][j]);
            if (this.sdArr[i][k]) yArr.push(this.sdArr[i][k]);
        }
        return this.getSumArr(xArr, yArr);
    },
    getThArr: function (i, j) {
        let minX, maxX;
        let minY, maxY;
        let sqrtN = Math.sqrt(this.num);
        for (let k = 0; k <= sqrtN; k++) {
            if (i >= k * sqrtN && i < (k + 1) * sqrtN) {
                minX = k * sqrtN;
                maxX = (k + 1) * sqrtN;
            }

            if (j >= k * sqrtN && j < (k + 1) * sqrtN) {
                minY = k * sqrtN;
                maxY = (k + 1) * sqrtN;
            }
        }

        let arr = [];
        for (let x = minX; x < maxX; x++) {
            for (let y = minY; y < maxY; y++) {
                if (this.sdArr[x][y]) arr.push(this.sdArr[x][y]);
            }
        }
        return arr;
    },
    getSumArr: function (arr1, arr2) {
        var arr = arr1.slice();
        arr2.forEach((item, i) => {
            if (arr1.indexOf(item) < 0) arr.push(item);
        });
        return arr;
    },
    getResArr: function (arr1, arr2) {
        var arr = [];
        arr2.forEach((item, i) => {
            if (arr1.indexOf(item) < 0) arr.push(item);
        });
        return arr;
    },
    createBlank: function () {
        let count = 1;
        do {
            let i = parseInt(Math.random() * this.num);
            let j = parseInt(Math.random() * this.num);
            if (this.sdArr[i][j]) {
                this.sdArr[i][j] = '';
                count++;
            }
        } while (count <= Math.pow(this.num, 2) / 2);
    }
};